#ifndef __FIBER_IOMANAGER_H__
#define __FIBER_IOMANAGER_H__

#include <fcntl.h>         // 文件控制相关函数（如fcntl）
#include <cstring>         // 字符串操作函数
#include <sys/epoll.h>     // epoll相关系统调用
#include "timer.h"         // 定时器管理器基类
#include "scheduler.h"     // 调度器基类，用于协程调度
#include <functional>

namespace fiber 
{
// IO事件类型枚举（使用位运算支持事件组合）
enum Event {
    NONE = 0x0,   // 无事件
    READ = 0x1,   // 读事件（对应EPOLLIN）
    WRITE = 0x4   // 写事件（对应EPOLLOUT）
};

// 事件上下文：存储事件触发时的执行环境
struct EventContext {
    Scheduler* m_scheduler = nullptr;  // 事件所属的调度器
    Fiber::ptr m_fiber;                // 事件触发时需要执行的协程
    std::function<void()> m_cb;        // 事件触发时的回调函数（替代协程的执行方式）
};

// 文件描述符上下文：管理单个fd的所有事件信息
class FdContext {
    friend class IOManager;  // IOManager可访问私有成员

public:
    // 获取指定事件的上下文（读/写事件）
    EventContext& getEveContext(Event event);
    // 重置事件上下文（清空调度器、协程和回调）
    void resetEveContext(EventContext& ctx);
    // 触发指定事件（执行对应的协程或回调）
    void triggerEvent(Event event);

private:
    EventContext m_read;           // 读事件上下文
    EventContext m_write;          // 写事件上下文
    int m_fd = 0;                  // 关联的文件描述符
    Event m_event = NONE;   // 当前注册的事件集合（位运算组合）
    Mutex m_mutex;                 // 保护事件操作的互斥锁
};

// IO管理器：继承调度器（处理协程）和定时器管理器（处理定时任务）
class IOManager : public Scheduler, public TimerManager {
public:
    using ptr = std::shared_ptr<IOManager>;  // 智能指针类型定义

    // 构造函数：指定线程数、是否使用调用线程、名称
    IOManager(size_t threads = 1, bool use_caller = true, const std::string &name = "IOManager");
    ~IOManager();

    // 添加IO事件：监听fd上的event，触发时执行cb（或当前协程）
    int addEvent(int fd, Event event, std::function<void()> cb = nullptr);
    // 删除IO事件：从监听中移除fd上的event（不触发回调）
    bool delEvent(int fd, Event event);
    // 取消IO事件：移除fd上的event，并触发一次回调（标记取消）
    bool cancelEvent(int fd, Event event);
    // 取消fd上的所有事件，并触发回调
    bool cancelAll(int fd);

    // 获取当前线程的IOManager实例
    static IOManager *GetThis();

protected:
    // 通知调度器有新任务（唤醒等待的线程）
    void tickle() override;
    // 判断调度器是否可以停止（无任务、无事件、无定时器）
    bool stopping() override;
    // 空闲协程：当无任务时执行，负责epoll等待事件
    void idle() override;
    // 带超时的停止判断：获取最近的定时器超时时间
    bool stopping(uint64_t &timeout);

    // 当定时器插入到头部时调用（用于调整epoll等待超时）
    void OnTimerInsertedAtFront() override;
    // 调整fd上下文数组大小（动态扩容）
    void contextResize(size_t size);

private:
    int m_epfd = 0;                   // epoll实例的文件描述符
    int m_tickleFds[2];               // 用于线程间通知的管道（唤醒idle协程）
    std::atomic<size_t> m_pendingEventCnt = {0};  // 待处理的IO事件数量（原子操作保证线程安全）
    RWMutex m_rwmutex;                // 保护fdContexts的读写锁
    std::vector<FdContext*> m_fdContexts;  // 存储所有fd的上下文信息
};

}  // namespace fiber

#endif  // __FIBER_IOMANAGER_H__